/* -*-c++-*- */
/* osgGIS - GIS Library for OpenSceneGraph
 * Copyright 2007-2008 Glenn Waldron and Pelican Ventures, Inc.
 * http://osggis.org
 *
 * osgGIS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

#ifndef _OSGGIS_FEATURE_CURSOR_H_
#define _OSGGIS_FEATURE_CURSOR_H_

#include <osgGIS/Feature>

namespace osgGIS
{
    class FeatureStore;

    /**
     * Object that iterates over a collection of Features.
     *
     * This is a simple "cursor" implementation that uses a list of Feature OIDs
     * to iterate over a feature store.
     */
    class OSGGIS_EXPORT FeatureCursor
    {
    public:
        /**
         * Constructs a feature cursor
         *
         * @param oids
         *      Object IDs of features over which to iterate
         * @param store
         *      Feature store from which to read the Feature data
         * @param search_extent
         *      Search extent that was used to generate the list of OIDs in this
         *      cursor - this is used to refine the list of Features actually
         *      returned from the cursor
         * @param match_exactly
         *      True to only return Feature instances that "exactly" match the 
         *      original search criteria. When querying a FeatureStore by spatial
         *      extent (GeoExtent), the store will actually return a FeatureCursor
         *      corresponding to all features whose bounding extents intersect the
         *      search extent; i.e. it does not test down to the shape level. Passing
         *      true to this parameter will perform shape-level intersection testing
         *      when using this cursor.
         */
        FeatureCursor( 
            const FeatureOIDList& oids,
            FeatureStore*         store,
            const GeoExtent&      search_extent,
            bool                  match_exactly );

        /**
         * Constructs a feature cursor that will return no elements.
         */
        FeatureCursor();

        /**
         * Copy constructor
         */
        FeatureCursor( const FeatureCursor& rhs );

        virtual ~FeatureCursor();

        /**
         * Sets the number of Feature instances that the cursor will fetch and
         * cache at a time before having to reconnect to the FeatureStore.
         *
         * @param size
         *      Cache size for pre-fetch operations; default = 64
         */
        void setPrefetchSize( int size );

    public:

        /**
         * Resets the iterator to the beginning of the result set.
         */
        void reset();
        
        /**
         * Checks whether a call to next() would return a Feature
         *
         * @return
         *      True if there are more elements over which to iterate; false if we
         *      are at the end of the list
         */
        bool hasNext() const;

        /**
         * Gets the next feature in the list.
         *
         * @return
         *      Feature instance, or NULL if we're at the end
         */
        Feature* next();


    private:
        bool                       at_bof;
        FeatureOIDList             oids;
        unsigned int               iter;
        osg::ref_ptr<FeatureStore> store;
        osg::ref_ptr<Feature>      last_result;
        GeoExtent                  search_extent;
        bool                       match_exactly;
        FeatureQueue               prefetched_results;

    private:
        void prefetch();
        int prefetch_size;
    };
}

#endif // _OSGGIS_FEATURE_CURSOR_H_
